package com.jlpay.open.jlpay.sdk.java.utils.gm.keyentity;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.jlpay.open.jlpay.sdk.java.utils.gm.BcecUtils;
import com.jlpay.open.jlpay.sdk.java.utils.gm.Sm2Utils;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;

import java.util.Base64;

/**
 * SM2密钥实体
 *
 * @author zhangyinda
 * @since 2024/02/20
 */
@Data
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Sm2KeyEntity {
    /**
     * 公钥
     */
    private BCECPublicKey pubKey;

    /**
     * 私钥
     */
    private BCECPrivateKey priKey;

    public void initPriKey(String priKey) {
        try {
            byte[] priKeyData = BcecUtils.convertEcPrivateKeyPemToPkcs8(priKey);
            this.priKey = BcecUtils.convertPkcs8ToEcPrivateKey(priKeyData);
        } catch (Exception e) {
            throw new RuntimeException("Init PriKey Fail: " + e);
        }
    }

    public void initPubKey(String pubKey) {
        try {
            byte[] pubKeyData = BcecUtils.convertEcPublicKeyPemToX509(pubKey);
            this.pubKey = BcecUtils.convertX509ToEcPublicKey(pubKeyData);
        } catch (Exception e) {
            throw new RuntimeException("Init PubKey Fail: " + e);
        }
    }

    public String encrypt(String plaintext) {
        try {
            byte[] result = Sm2Utils.encrypt(pubKey, Base64.getDecoder().decode(plaintext));
            return new String(Base64.getEncoder().encode(result));
        } catch (Exception e) {
            throw new RuntimeException("Sm2 encrypt Fail: " + e);
        }
    }

    public String decrypt(String ciphertext) {
        try {
            byte[] result = Sm2Utils.decrypt(priKey, Base64.getDecoder().decode(ciphertext));
            return new String(Base64.getEncoder().encode(result));
        } catch (Exception e) {
            throw new RuntimeException("Sm2 decrypt Fail: " + e);
        }
    }
}
